package br.senac.sp.persistence.unityofwork;

import java.util.ArrayList;
import java.util.List;

import br.senac.sp.persistence.IConnector;
import br.senac.sp.persistence.PersistenceFacade;
import br.senac.sp.persistence.unityofwork.command.DeleteCommand;
import br.senac.sp.persistence.unityofwork.command.ICommand;
import br.senac.sp.persistence.unityofwork.command.InsertCommand;
import br.senac.sp.persistence.unityofwork.command.UpdateCommand;

public class Transaction {

    private List<ICommand> insertCommands;
    private List<ICommand> updateCommands;
    private List<ICommand> deleteCommands;

    public Transaction() {
        insertCommands = new ArrayList<ICommand>();
        updateCommands = new ArrayList<ICommand>();
        deleteCommands = new ArrayList<ICommand>();
        connector().informTransactionCreation();
    }
    
    public <Entity, OID> void addInsert(Entity entity) {
        insertCommands.add(new InsertCommand<Entity>(entity));
    }
    
    public <Entity, OID> void addDelete(Entity entity) {
        deleteCommands.add(new DeleteCommand<Entity, OID>(entity));
    }
    
    public <Entity, OID> void addUpdate(Entity entity) {
        updateCommands.add(new UpdateCommand<Entity>(entity));
    }
    
    public void flush() {
        //essa ordem deveria ser variavel e depende de um monte de coisas.... :P
        executeCommands(insertCommands);
        executeCommands(updateCommands);
        executeCommands(deleteCommands);
        clearCommands();
    }

    public void commit() {
        flush();
        connector().informTransactionCommit();
    }
    
    public void rollback() {
        //limpamos nossa lista de comandos... talvez tenhamos que reorganizar o cache ou limpa-lo
        clearCommands();
        connector().informTransactionRollback();
    }

    private void clearCommands() {
        deleteCommands.clear();
        updateCommands.clear();
        insertCommands.clear();
    }
    
    private void executeCommands(List<ICommand> commands) {
        for (ICommand command : commands) {
            command.execute();
        }
    }

    private static IConnector connector() {
        return PersistenceFacade.getInstance().getConnector();
    }
}
